#ifndef _KMEANS_H
#define _KMEANS_H

#include "Cluster.h"

#include <vector>

using namespace std;

class KMeans : public Cluster {
public:
    void cluster(vector<Sample *> &sampleList);

    /**
     * @param sampleSpace context, to assure that s_dim of Sample is fixed so that new _Center operation is valid
     * @param K
     */
    KMeans(SampleSpace &sampleSpace, int K): Cluster(sampleSpace) {
        m_K = K;
    }
    
    /**
     * @param sampleSpace context, to assure that s_dim of Sample is fixed so that new _Center operation is valid
     * @param K
     * @param init the initial samples in cluster function
     */
    KMeans(SampleSpace &sampleSpace, int K, vector<Sample *> &init);
    ~KMeans();

private:
    int m_K;
    vector<Sample *> m_init;

    KMeans(const KMeans &kmeans);

    /**
     * It's safe to instantiate an object without noticing whether Sample's m_dim is initialized, for class
     * KMeans's instantiation needs the reference of the SampleSpace object, of which the instantiating
     * process must initialized the Sample's m_dim.
     */
    class _Center : public Sample {
    public:

        vector<Sample *> & getSampleList() {
            return m_sampleList;
        }

        int getSampleCount() {
            return m_sampleList.size();
        }

        void addSample(Sample *sample) {
            m_sampleList.push_back(sample);
        }

        void clearSample() {
            m_sampleList.clear();
        }

        /**
         * Calculate the mean of all samples, and move the center to the mean point.
         * Return true if the moving distance is not zero, else return false.
         */
        bool move2center();

        _Center(int dim): Sample(dim) {
        }

        /*
        _Center(int dim, int _class): Sample(dim, _class) {
        }

        _Center(int dim, int _class, float *data): Sample(dim, _class, data) {
        }

        _Center(const Sample &sample): Sample(sample) {
        }*/

    private:
        vector<Sample *> m_sampleList;

    };

};

#endif
